package com.qf.rbac2202.sys.service.impl;

import com.baomidou.mybatisplus.core.conditions.query.LambdaQueryWrapper;
import com.baomidou.mybatisplus.core.conditions.query.QueryWrapper;
import com.baomidou.mybatisplus.core.toolkit.StringUtils;
import com.baomidou.mybatisplus.extension.plugins.pagination.Page;
import com.qf.rbac2202.sys.entity.SysRole;
import com.qf.rbac2202.sys.entity.SysRoleDept;
import com.qf.rbac2202.sys.entity.SysRoleMenu;
import com.qf.rbac2202.sys.mapper.SysRoleMapper;
import com.qf.rbac2202.sys.service.ISysRoleDeptService;
import com.qf.rbac2202.sys.service.ISysRoleMenuService;
import com.qf.rbac2202.sys.service.ISysRoleService;
import com.baomidou.mybatisplus.extension.service.impl.ServiceImpl;
import com.qf.rbac2202.sys.service.ISysUserRoleService;
import com.qf.rbac2202.utils.PageQueryUtil;
import com.qf.rbac2202.utils.PageVo;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Service;
import org.springframework.transaction.annotation.Propagation;
import org.springframework.transaction.annotation.Transactional;

import java.util.Date;
import java.util.List;
import java.util.Map;
import java.util.stream.Collectors;

/**
 * <p>
 * 角色 服务实现类
 * </p>
 *
 * @author dong_
 * @since 2022-10-28
 */
@Service
public class SysRoleServiceImpl extends ServiceImpl<SysRoleMapper, SysRole> implements ISysRoleService {

    @Autowired
    ISysRoleMenuService sysRoleMenuService;

    @Autowired
    ISysRoleDeptService sysRoleDeptService;


    @Transactional(propagation = Propagation.SUPPORTS)
    @Override
    public PageVo<SysRole> queryByPage(Map<String, String> parmas) {

        // 1. 创建分页对象
        final Page<SysRole> page = PageQueryUtil.getPage(parmas);

        // 2. 创建查询对象
        final LambdaQueryWrapper<SysRole> queryWrapper = new LambdaQueryWrapper<>();
        final String roleName = parmas.get("roleName");
        queryWrapper.eq(StringUtils.isNotBlank(roleName),SysRole::getRoleName,roleName);

        // 3. 执行分页查询
        this.page(page,queryWrapper);

        return new PageVo<SysRole>(page);
    }

    @Transactional(rollbackFor = Exception.class)
    @Override
    public void saveRole(SysRole sysRole) {

        //1. 保存角色基本信息
        sysRole.setCreateTime(new Date());

        this.save(sysRole);

        // 获取主键回填产生的roleid
        final Long roleId = sysRole.getRoleId();

        //2. 保存角色和菜单的对应关系
        final List<Long> menuIdList = sysRole.getMenuIdList();

        // List<菜单ID> ---->  List<SysRoleMenu>
        /**
         *                     final SysRoleMenu sysRoleMenu = new SysRoleMenu();
         *                     sysRoleMenu.setMenuId(menuId);
         *                     sysRoleMenu.setRoleId(roleId);
         *                     return sysRoleMenu;
         */
        final List<SysRoleMenu> sysRoleMenuList = menuIdList.stream()
                .map(menuId -> new SysRoleMenu(roleId,menuId) )
                .collect(Collectors.toList());

        sysRoleMenuService.saveBatch(sysRoleMenuList);

        // 3. 保存角色和部门的对应关系
        final List<Long> deptIdList = sysRole.getDeptIdList();
        final List<SysRoleDept> sysRoleDeptList = deptIdList.stream()
                .map(deptId -> new SysRoleDept(roleId, deptId))
                .collect(Collectors.toList());
        sysRoleDeptService.saveBatch(sysRoleDeptList);

    }

    @Transactional(propagation = Propagation.SUPPORTS)
    @Override
    public SysRole getRoleById(Long roleId) {

        //1. 查角色基本信息
        final SysRole role = this.getById(roleId);

        //2. 查角色对应的菜单信息
        final QueryWrapper<SysRoleMenu> sysRoleMenuQueryWrapper = new QueryWrapper<>();
        sysRoleMenuQueryWrapper.select("menu_id");
        sysRoleMenuQueryWrapper.eq("role_id",roleId);
        final List<Object> menuIdList = sysRoleMenuService.listObjs(sysRoleMenuQueryWrapper);
        // List<Object> --> List<Long>
        final List<Long> menuIdLongList = menuIdList.stream()
                .map(o -> ((Long) o))
                .collect(Collectors.toList());

        role.setMenuIdList(menuIdLongList);

        //3. 查询角色对应的部门信息
        final QueryWrapper<SysRoleDept> sysRoleDeptQueryWrapper = new QueryWrapper<>();
        sysRoleDeptQueryWrapper.select("dept_id");
        sysRoleDeptQueryWrapper.eq("role_id",roleId);
        final List<Object> deptIdList = sysRoleDeptService.listObjs(sysRoleDeptQueryWrapper);
        final List<Long> deptIdLongList = deptIdList.stream()
                .map(o -> ((Long) o))
                .collect(Collectors.toList());

        role.setDeptIdList(deptIdLongList);

        return role;
    }

    @Transactional(rollbackFor = Exception.class)
    @Override
    public void updateRole(SysRole sysRole) {

        //1. 更新 角色基本信息 ，sys_role
        this.updateById(sysRole);

        //2. 更新 sys_role_menu
        //2.1 先把 该角色对应 的sys_role_menu表中的数据删除

        final QueryWrapper<SysRoleMenu> sysRoleMenuQueryWrapper = new QueryWrapper<>();
        sysRoleMenuQueryWrapper.eq("role_id",sysRole.getRoleId());
        sysRoleMenuService.remove(sysRoleMenuQueryWrapper);

        //2.2 再重新插入数据
        final List<Long> menuIdList = sysRole.getMenuIdList();
        // List<菜单ID> ---->  List<SysRoleMenu>
        final Long roleId = sysRole.getRoleId();
        final List<SysRoleMenu> sysRoleMenuList = menuIdList.stream()
                .map(menuId -> new SysRoleMenu(roleId,menuId) )
                .collect(Collectors.toList());
        sysRoleMenuService.saveBatch(sysRoleMenuList);

        //3. 更新 sys_role_dept

        final QueryWrapper<SysRoleDept> sysRoleDeptQueryWrapper = new QueryWrapper<>();
        sysRoleDeptQueryWrapper.eq("role_id",roleId);
        sysRoleDeptService.remove(sysRoleDeptQueryWrapper);

        final List<Long> deptIdList = sysRole.getDeptIdList();
        final List<SysRoleDept> sysRoleDeptList = deptIdList.stream()
                .map(deptId -> new SysRoleDept(roleId, deptId))
                .collect(Collectors.toList());
        sysRoleDeptService.saveBatch(sysRoleDeptList);

    }
}
